/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tcc.ejb.controleProjeto.controle;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import tcc.ejb.controleProjeto.controle.exceptions.IllegalOrphanException;
import tcc.ejb.controleProjeto.controle.exceptions.NonexistentEntityException;
import tcc.ejb.controleProjeto.controle.exceptions.PreexistingEntityException;
import tcc.ejb.controleProjeto.entidade.Release;
import tcc.ejb.controleProjeto.entidade.Atividade;
import java.util.ArrayList;
import java.util.List;
import tcc.ejb.controleProjeto.entidade.Tarefa;

/**
 *
 * @author Maciel
 */
public class AtividadeJpaController {

    public AtividadeJpaController() {
        emf = Persistence.createEntityManagerFactory("WebApplication4PU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Atividade atividade) throws PreexistingEntityException, Exception {
        if (atividade.getAtividadeList() == null) {
            atividade.setAtividadeList(new ArrayList<Atividade>());
        }
        if (atividade.getAtividadeList1() == null) {
            atividade.setAtividadeList1(new ArrayList<Atividade>());
        }
        if (atividade.getTarefaList() == null) {
            atividade.setTarefaList(new ArrayList<Tarefa>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Release release = atividade.getRelease();
            if (release != null) {
                release = em.getReference(release.getClass(), release.getId());
                atividade.setRelease(release);
            }
            List<Atividade> attachedAtividadeList = new ArrayList<Atividade>();
            for (Atividade atividadeListAtividadeToAttach : atividade.getAtividadeList()) {
                atividadeListAtividadeToAttach = em.getReference(atividadeListAtividadeToAttach.getClass(), atividadeListAtividadeToAttach.getId());
                attachedAtividadeList.add(atividadeListAtividadeToAttach);
            }
            atividade.setAtividadeList(attachedAtividadeList);
            List<Atividade> attachedAtividadeList1 = new ArrayList<Atividade>();
            for (Atividade atividadeList1AtividadeToAttach : atividade.getAtividadeList1()) {
                atividadeList1AtividadeToAttach = em.getReference(atividadeList1AtividadeToAttach.getClass(), atividadeList1AtividadeToAttach.getId());
                attachedAtividadeList1.add(atividadeList1AtividadeToAttach);
            }
            atividade.setAtividadeList1(attachedAtividadeList1);
            List<Tarefa> attachedTarefaList = new ArrayList<Tarefa>();
            for (Tarefa tarefaListTarefaToAttach : atividade.getTarefaList()) {
                tarefaListTarefaToAttach = em.getReference(tarefaListTarefaToAttach.getClass(), tarefaListTarefaToAttach.getId());
                attachedTarefaList.add(tarefaListTarefaToAttach);
            }
            atividade.setTarefaList(attachedTarefaList);
            em.persist(atividade);
            if (release != null) {
                release.getAtividadeList().add(atividade);
                release = em.merge(release);
            }
            for (Atividade atividadeListAtividade : atividade.getAtividadeList()) {
                atividadeListAtividade.getAtividadeList().add(atividade);
                atividadeListAtividade = em.merge(atividadeListAtividade);
            }
            for (Atividade atividadeList1Atividade : atividade.getAtividadeList1()) {
                atividadeList1Atividade.getAtividadeList().add(atividade);
                atividadeList1Atividade = em.merge(atividadeList1Atividade);
            }
            for (Tarefa tarefaListTarefa : atividade.getTarefaList()) {
                Atividade oldAtividadeOfTarefaListTarefa = tarefaListTarefa.getAtividade();
                tarefaListTarefa.setAtividade(atividade);
                tarefaListTarefa = em.merge(tarefaListTarefa);
                if (oldAtividadeOfTarefaListTarefa != null) {
                    oldAtividadeOfTarefaListTarefa.getTarefaList().remove(tarefaListTarefa);
                    oldAtividadeOfTarefaListTarefa = em.merge(oldAtividadeOfTarefaListTarefa);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findAtividade(atividade.getId()) != null) {
                throw new PreexistingEntityException("Atividade " + atividade + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Atividade atividade) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Atividade persistentAtividade = em.find(Atividade.class, atividade.getId());
            Release releaseOld = persistentAtividade.getRelease();
            Release releaseNew = atividade.getRelease();
            List<Atividade> atividadeListOld = persistentAtividade.getAtividadeList();
            List<Atividade> atividadeListNew = atividade.getAtividadeList();
            List<Atividade> atividadeList1Old = persistentAtividade.getAtividadeList1();
            List<Atividade> atividadeList1New = atividade.getAtividadeList1();
            List<Tarefa> tarefaListOld = persistentAtividade.getTarefaList();
            List<Tarefa> tarefaListNew = atividade.getTarefaList();
            List<String> illegalOrphanMessages = null;
            for (Tarefa tarefaListOldTarefa : tarefaListOld) {
                if (!tarefaListNew.contains(tarefaListOldTarefa)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Tarefa " + tarefaListOldTarefa + " since its atividade field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (releaseNew != null) {
                releaseNew = em.getReference(releaseNew.getClass(), releaseNew.getId());
                atividade.setRelease(releaseNew);
            }
            List<Atividade> attachedAtividadeListNew = new ArrayList<Atividade>();
            for (Atividade atividadeListNewAtividadeToAttach : atividadeListNew) {
                atividadeListNewAtividadeToAttach = em.getReference(atividadeListNewAtividadeToAttach.getClass(), atividadeListNewAtividadeToAttach.getId());
                attachedAtividadeListNew.add(atividadeListNewAtividadeToAttach);
            }
            atividadeListNew = attachedAtividadeListNew;
            atividade.setAtividadeList(atividadeListNew);
            List<Atividade> attachedAtividadeList1New = new ArrayList<Atividade>();
            for (Atividade atividadeList1NewAtividadeToAttach : atividadeList1New) {
                atividadeList1NewAtividadeToAttach = em.getReference(atividadeList1NewAtividadeToAttach.getClass(), atividadeList1NewAtividadeToAttach.getId());
                attachedAtividadeList1New.add(atividadeList1NewAtividadeToAttach);
            }
            atividadeList1New = attachedAtividadeList1New;
            atividade.setAtividadeList1(atividadeList1New);
            List<Tarefa> attachedTarefaListNew = new ArrayList<Tarefa>();
            for (Tarefa tarefaListNewTarefaToAttach : tarefaListNew) {
                tarefaListNewTarefaToAttach = em.getReference(tarefaListNewTarefaToAttach.getClass(), tarefaListNewTarefaToAttach.getId());
                attachedTarefaListNew.add(tarefaListNewTarefaToAttach);
            }
            tarefaListNew = attachedTarefaListNew;
            atividade.setTarefaList(tarefaListNew);
            atividade = em.merge(atividade);
            if (releaseOld != null && !releaseOld.equals(releaseNew)) {
                releaseOld.getAtividadeList().remove(atividade);
                releaseOld = em.merge(releaseOld);
            }
            if (releaseNew != null && !releaseNew.equals(releaseOld)) {
                releaseNew.getAtividadeList().add(atividade);
                releaseNew = em.merge(releaseNew);
            }
            for (Atividade atividadeListOldAtividade : atividadeListOld) {
                if (!atividadeListNew.contains(atividadeListOldAtividade)) {
                    atividadeListOldAtividade.getAtividadeList().remove(atividade);
                    atividadeListOldAtividade = em.merge(atividadeListOldAtividade);
                }
            }
            for (Atividade atividadeListNewAtividade : atividadeListNew) {
                if (!atividadeListOld.contains(atividadeListNewAtividade)) {
                    atividadeListNewAtividade.getAtividadeList().add(atividade);
                    atividadeListNewAtividade = em.merge(atividadeListNewAtividade);
                }
            }
            for (Atividade atividadeList1OldAtividade : atividadeList1Old) {
                if (!atividadeList1New.contains(atividadeList1OldAtividade)) {
                    atividadeList1OldAtividade.getAtividadeList().remove(atividade);
                    atividadeList1OldAtividade = em.merge(atividadeList1OldAtividade);
                }
            }
            for (Atividade atividadeList1NewAtividade : atividadeList1New) {
                if (!atividadeList1Old.contains(atividadeList1NewAtividade)) {
                    atividadeList1NewAtividade.getAtividadeList().add(atividade);
                    atividadeList1NewAtividade = em.merge(atividadeList1NewAtividade);
                }
            }
            for (Tarefa tarefaListNewTarefa : tarefaListNew) {
                if (!tarefaListOld.contains(tarefaListNewTarefa)) {
                    Atividade oldAtividadeOfTarefaListNewTarefa = tarefaListNewTarefa.getAtividade();
                    tarefaListNewTarefa.setAtividade(atividade);
                    tarefaListNewTarefa = em.merge(tarefaListNewTarefa);
                    if (oldAtividadeOfTarefaListNewTarefa != null && !oldAtividadeOfTarefaListNewTarefa.equals(atividade)) {
                        oldAtividadeOfTarefaListNewTarefa.getTarefaList().remove(tarefaListNewTarefa);
                        oldAtividadeOfTarefaListNewTarefa = em.merge(oldAtividadeOfTarefaListNewTarefa);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = atividade.getId();
                if (findAtividade(id) == null) {
                    throw new NonexistentEntityException("The atividade with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Atividade atividade;
            try {
                atividade = em.getReference(Atividade.class, id);
                atividade.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The atividade with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Tarefa> tarefaListOrphanCheck = atividade.getTarefaList();
            for (Tarefa tarefaListOrphanCheckTarefa : tarefaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Atividade (" + atividade + ") cannot be destroyed since the Tarefa " + tarefaListOrphanCheckTarefa + " in its tarefaList field has a non-nullable atividade field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Release release = atividade.getRelease();
            if (release != null) {
                release.getAtividadeList().remove(atividade);
                release = em.merge(release);
            }
            List<Atividade> atividadeList = atividade.getAtividadeList();
            for (Atividade atividadeListAtividade : atividadeList) {
                atividadeListAtividade.getAtividadeList().remove(atividade);
                atividadeListAtividade = em.merge(atividadeListAtividade);
            }
            List<Atividade> atividadeList1 = atividade.getAtividadeList1();
            for (Atividade atividadeList1Atividade : atividadeList1) {
                atividadeList1Atividade.getAtividadeList().remove(atividade);
                atividadeList1Atividade = em.merge(atividadeList1Atividade);
            }
            em.remove(atividade);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Atividade> findAtividadeEntities() {
        return findAtividadeEntities(true, -1, -1);
    }

    public List<Atividade> findAtividadeEntities(int maxResults, int firstResult) {
        return findAtividadeEntities(false, maxResults, firstResult);
    }

    private List<Atividade> findAtividadeEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Atividade.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Atividade findAtividade(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Atividade.class, id);
        } finally {
            em.close();
        }
    }

    public int getAtividadeCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Atividade> rt = cq.from(Atividade.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
